iT邦幫忙

2024 iThome 鐵人賽

DAY 12
1
Software Development

Laravel 隨筆學習札記系列 第 12

Day12 - Laravel Eager Loading vs. Lazy Loading

  • 分享至 

  • xImage
  •  

好,今天不想開書店,改來開咖啡廳好了XD>

在一個村落裡,有一間很好喝的咖啡店,店內特色就是老闆的咖啡有精心搭配的特定甜點。每杯咖啡都可能搭配一種或多種甜點。店長希望顧客在點咖啡時,能先快速看到咖啡的資訊,而不需要浪費資源來加載所有甜點的資料。

下面分別來說說使用 Lazy Loading 和 Eager Loading 會產生什麼後續故事呢?


Lazy Loading

顧客進入咖啡店時,首先只看到咖啡的菜單。當顧客點了某杯咖啡並詢問搭配的甜點時,系統才去查詢該咖啡的甜點資訊。

這樣可以減少初始加載的數據,但在顧客每次詢問甜點時,系統都會增加一次查詢。

多對多的資料表 CoffeeDessert

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;

class Coffee extends Model
{
    /**
     * Get the desserts that go with the coffee.
     */
    public function desserts(): BelongsToMany
    {
        return $this->belongsToMany(Dessert::class);
    }
}

使用 Lazy Loading 不會直接與咖啡有關的甜點資料,是先加載全部咖啡資料,容易導致查詢次數增加,當我們使用 $coffee->desserts 時,Laravel 會發出查詢請求來獲取該咖啡的甜點資料,這在有許多咖啡時會造成 N+1 查詢問題。

use App\Models\Coffee;

$coffees = Coffee::all(); // 這裡加載全部咖啡資料

foreach ($coffees as $coffee) {
    echo $coffee->name . "\\n";
    echo "搭配的甜點:\\n";
    foreach ($coffee->desserts as $dessert) {
        echo $dessert->name . "\\n"; // 每次訪問時都會查詢甜點
    }
}

Eager Loading

顧客一進咖啡店,店主就將所有咖啡和它們搭配的甜點一起展示出來。這樣在顧客查看咖啡時,也一次性加載了甜點資料,避免了多次查詢。

使用 Eager Loading 的 with 方法可以指定要預先載入哪些關係,with('desserts') 使 Laravel 一次性查詢所有咖啡及其甜點資料,從而提高效能,特別是在資料量大的時候。

// 使用 Eager Loading 加載咖啡及其甜點
$coffees = Coffee::with('desserts')->get(); // 一次加載所有咖啡和相關甜點

foreach ($coffees as $coffee) {
    echo $coffee->name . "\\n";
    echo "搭配的甜點:\\n";
    foreach ($coffee->desserts as $dessert) {
        echo $dessert->name . "\\n"; // 不會額外查詢
    }
}


比較差異

Eager Loading vs. Lazy Loading 差異


使用時機

Lazy Loading

  • 當關聯資料量少且不經常需要顯示時。
  • 當需要提高初始加載速度或資源有限的情況下。

Eager Loading

  • 當需要顯示大量關聯資料時,例如在顯示列表或報告時。
  • 當確定需要訪問所有相關資料,避免 N+1 查詢問題時。

參考資料

  1. Lazy Loading vs Eager Loading
  2. Laravl官方網站 - Eager Loading
  3. Eager vs. Lazy Loading in Laravel: Optimizing Database Queries for Efficient Data Retrieval in Web Applications.
  4. The Difference between Eager Loading vs Lazy Loading

踏著身心靈的塔羅腳步,轉向技術與邏輯的工程師之路,就藉由塔羅日抽來紀錄今日的學習與生活吧!

惡魔牌:惡魔牌象徵認真執著,Eager vs. Lazy 兩個皆有好壞,不需要堅持使用哪一種,可以在深入了解後,選擇自己需要的。

"Would you tell me, please, which way I ought to go from here?" said Alice.
"That depends a good deal on where you want to get to," said the Cat.
"I don't much care where--" said Alice.
"Then it doesn't matter which way you go," said the Cat.
"... so long as I get somewhere," Alice added as an explanation.
"Oh, you're sure to do that," said the Cat, "if you only walk long enough."

「如果你不知道你要去哪裡,那麼現在你在哪裡一點都不重要。
 只要你一直走,總會走到什麼地方的。」

― Lewis Carroll, Alice in Wonderland


上一篇
Day11 - Laravel Eloquent: Factories 
下一篇
Day13 - Laravel Routing
系列文
Laravel 隨筆學習札記13
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言